package com.tzh.plugin.utils;

import com.github.pagehelper.util.StringUtil;
import com.tzh.utils.PropertiesUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaElement;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.config.TableConfiguration;
import org.springframework.util.StringUtils;

import javax.validation.constraints.Max;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

public class PluginAnnotationUtils {


    private static final FullyQualifiedJavaType apiModelAnnotation;

    private static final FullyQualifiedJavaType apiModelPropertyAnnotation;

    private static final FullyQualifiedJavaType maxModelAnnotation;

    private static final FullyQualifiedJavaType noArgsConstructorModelAnnotation;

    private static final FullyQualifiedJavaType allArgsConstructorModelAnnotation;

    private static final FullyQualifiedJavaType dataAnnotation;
//    private static final FullyQualifiedJavaType toStringModelAnnotation;

    static {
        apiModelAnnotation = new FullyQualifiedJavaType(ApiModel.class.getTypeName());
        apiModelPropertyAnnotation = new FullyQualifiedJavaType(ApiModelProperty.class.getTypeName());
        maxModelAnnotation = new FullyQualifiedJavaType(Max.class.getTypeName());
        noArgsConstructorModelAnnotation = new FullyQualifiedJavaType(NoArgsConstructor.class.getTypeName());
        allArgsConstructorModelAnnotation = new FullyQualifiedJavaType(AllArgsConstructor.class.getTypeName());
        dataAnnotation = new FullyQualifiedJavaType(Data.class.getTypeName());
//      toStringModelAnnotation = new FullyQualifiedJavaType(ToString.class.getTypeName());
    }

    public static void comment(JavaElement element, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        element.getJavaDocLines().clear();
        element.addJavaDocLine("/**");
        String remark = introspectedColumn.getRemarks();
        if (remark != null && remark.length() > 1) {
            element.addJavaDocLine(" * " + remark);
            element.addJavaDocLine(" *");
        }
        TableConfiguration config = introspectedTable.getTableConfiguration();
        Properties prop = config.getProperties();
        String comments = "...";
        String length = "0";
        if (prop != null) {
            String columnDbName = introspectedColumn.getActualColumnName();
            Object obj = prop.get(introspectedTable.getFullyQualifiedTableNameAtRuntime() + ":" + columnDbName);
            if (obj != null) {
                String propValue = obj.toString();
                String[] propArray = propValue.split(":", 3);
                String type = propArray[0];
                length = propArray[1];
                comments = propArray[2];
                if (StringUtil.isEmpty(comments) || "null".equals(comments)) {
                    comments = "---";
                }
            }

        }


        element.getJavaDocLines().clear();
        element.addJavaDocLine("/**");
        element.addJavaDocLine(" * 表名:     " + introspectedTable.getFullyQualifiedTable());
        element.addJavaDocLine(" * 列明:    " + introspectedColumn.getRemarks());
        element.addJavaDocLine(" * 是否可以为Null:  " + introspectedColumn.isNullable());
        element.addJavaDocLine(" */");
        introspectedColumn.getFullyQualifiedJavaType();
        System.out.println("-----------" + introspectedColumn.getJdbcType());
        element.addAnnotation("@ApiModelProperty(value = \"" + comments + "\"" + (StringUtils.isEmpty(introspectedColumn.getDefaultValue()) ? ",example=\"" + setExample(introspectedColumn) + "\"" : ",example = \"" +
                "" + introspectedColumn.getDefaultValue().replace("\n", "").replace("\\", "|") + "\"") + ")");
        element.addAnnotation("@Max(value=" + length + ",message=\"字段长度不超过" + length + "位\")");
//
    }

    public static String setExample(IntrospectedColumn introspectedColumn) {
        FullyQualifiedJavaType type = introspectedColumn.getFullyQualifiedJavaType();
        String typeName = type.getFullyQualifiedName();
        String shortType = Short.class.getName();
        String intType = Integer.class.getName();
        String LongType = Long.class.getName();
        String dateType = Date.class.getName();
        String bigDType = BigDecimal.class.getName();
        if (typeName.equals(shortType)) {
            return "0";
        } else if (typeName.equals(intType)) {
            return "0";
        } else if (typeName.equals(LongType)) {
            return "0";
        } else if (typeName.equals(dateType)) {
            return new Date().toString();
        } else if (typeName.equals(bigDType)) {
            return "0";
        } else {
            return "";
        }
    }

    /**
     * @param topLevelClass
     */
    public static void addDataAnnotation(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        Object obj = introspectedTable.getTableConfiguration().getProperties().get(introspectedTable.getFullyQualifiedTableNameAtRuntime() + ":comments");
        String tableComments = "";
        if (obj != null) {
            tableComments = obj.toString();
        }
        if (Boolean.valueOf(PropertiesUtils.getConfigValue("lombok.enabled", "false"))) {
            topLevelClass.addImportedType(dataAnnotation);
            topLevelClass.addAnnotation("@Data");
            topLevelClass.addImportedType(noArgsConstructorModelAnnotation);
            topLevelClass.addAnnotation("@NoArgsConstructor");
            topLevelClass.addImportedType(allArgsConstructorModelAnnotation);
            topLevelClass.addAnnotation("@AllArgsConstructor");
//          topLevelClass.addImportedType(toStringModelAnnotation);
//          topLevelClass.addAnnotation("@ToString");
        }
        topLevelClass.addImportedType(apiModelPropertyAnnotation);
        topLevelClass.addImportedType(apiModelAnnotation);
        topLevelClass.addImportedType(maxModelAnnotation);
        topLevelClass.addAnnotation("@ApiModel(value = \"" + tableComments + "\" ,description = \"" + tableComments + "\")");
        topLevelClass.getJavaDocLines().clear();
        topLevelClass.addJavaDocLine("/**");
        topLevelClass.addJavaDocLine(" * 表名: " + tableComments);
        topLevelClass.addJavaDocLine(" * Table: " + introspectedTable.getFullyQualifiedTable());
        topLevelClass.addJavaDocLine(" */");
    }


    public static void delDaoClassComment(Method method) {
        List<String> list = method.getJavaDocLines();
//       delDaoComment(list);
        list.clear();
    }


    private static void delDaoComment(List<String> list) {
        Iterator<String> it = list.iterator();
        int index = 0;
        int posi = 0;
        while (it.hasNext()) {
            String str = it.next();
            if (str.contains("/**")) {
                posi = index + 1;
            }
            if (str.contains("MyBatis Generator.")) {
                it.remove();
            }
            if (str.contains("corresponds to the database table")) {
                it.remove();
            }
            if (str.contains("@mbg.generated")) {
                it.remove();
            }
            index++;
        }
    }
}
